﻿using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Mvc;
using BlogPlat.Model;
using BlogPlat.Areas.Admin;
using BlogPlat.Areas.Admin.Controllers;
using AdminPostController = BlogPlat.Areas.Admin.Controllers.PostController;
using BlogPlat.Tests.Models;
using System.Text.RegularExpressions;
using BlogPlat.Tests.Helpers;

namespace BlogPlat.Tests.Areas.Admin.Controllers
{
    /// <summary>
    /// Summary description for AdminPostControllerTest
    /// </summary>
    [TestClass]
    public class AdminPostControllerTest
    {
        public AdminPostControllerTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void Admin_Index_Post_Return_List_Of_Posts()
        {
            // Arrange
            var repository = new FakePostRepository();
            List<Post> posts = Mock.CreateDummyBlogPostData();
            foreach (Post p in posts)
                repository.Add(p);

            var adminController = new AdminPostController(repository);

            // Act
            var result = (ViewResult)adminController.Index();

            // Assert
            CollectionAssert.AllItemsAreInstancesOfType((ICollection)result.ViewData.Model, typeof(Post));        
        }

        [TestMethod]
        // Test method for creating new blog post
        public void Admin_Can_Create_New_Post()
        {
            // Arrange
            var repository = new FakePostRepository();
            var controller = new AdminPostController(repository);
            var newPost = new Post { ID = 44, FriendlyUrl = "asd-dfdf-asdsd", DatePublished = new DateTime(2010, 6, 2), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 };

            // Act
            controller.Create(newPost);
            var result = (ViewResult)controller.Index();
            var firstEntry = (Post)((IList)result.ViewData.Model)[0];

            // Assert
            Assert.AreEqual(firstEntry.ID, newPost.ID);
        }

        [TestMethod]
        public void Admin_Create_New_Post_FriendlyUrl_IsValid()
        {
            // Arrange
            var repository = new FakePostRepository();
            var controller = new AdminPostController(repository);
            var newPost = new Post { ID = 44, FriendlyUrl = "$@sd asdsd", DatePublished = new DateTime(2010, 6, 2), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 };

            // Act
            controller.Create(newPost);
            var result = (ViewResult)controller.Index();            

            // Assert
            var blogEntries = (IList<Post>)result.ViewData.Model;
            StringAssert.DoesNotMatch(blogEntries[0].FriendlyUrl, new Regex("[\"$&+,/:;=?@]"));
            Assert.AreEqual(blogEntries[0].FriendlyUrl, "sd-asdsd");
        }

        [TestMethod]
        // Test method for deleting blog post
        public void Admin_Can_Delete_Post()
        {
            // Arrange
            var repository = new FakePostRepository();
            var controller = new AdminPostController(repository);
            for (int i = 1; i <= 5; i++)
            {
                var newPost = new Post { ID = i, FriendlyUrl = "test-1", DatePublished = new DateTime(2010, 6, 2), Author = "admin", CategoryID = 2, EnableComments = true, IsDraft = false, PostContent = "test-content", PostSummary = "test-summary", PostTitle = "test title", ViewCount = 9 };
                controller.Create(newPost);
            }

            // Act
            var deletedPost = repository.Get(3);
            controller.Delete(3);

            // Assert
            Assert.IsFalse(((IList)((ViewResult)controller.Index()).ViewData.Model).Contains(deletedPost));
        }
    }
}
